package com.gopay.bis.manager.bank.expay;

import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.bis.dao.payconfig.BisExpaySmsSendLogDAO;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.cust.SMSType;
import com.gopay.common.constants.trans.GatewaySource;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.icbc.expay.IcbcExpayCmsEbPubReq;
import com.gopay.common.domain.bank.icbc.expay.pay.req.IcbcExpayCmsEbInReq;
import com.gopay.common.domain.bank.icbc.expay.pay.req.IcbcExpayCmsEbReq;
import com.gopay.common.domain.bank.icbc.expay.pay.req.IcbcExpayCmsReq;
import com.gopay.common.domain.bank.icbc.expay.pay.res.IcbcExpayCmsRes;
import com.gopay.common.domain.bank.icbc.expay.prepay.req.IcbcPreExpayCmsEbInReq;
import com.gopay.common.domain.bank.icbc.expay.prepay.req.IcbcPreExpayCmsEbReq;
import com.gopay.common.domain.bank.icbc.expay.prepay.req.IcbcPreExpayCmsReq;
import com.gopay.common.domain.bank.icbc.expay.prepay.res.IcbcPreExpayCmsRes;
import com.gopay.common.domain.bank.icbc.expay.query.req.IcbcQueryExpayCmsEbInReq;
import com.gopay.common.domain.bank.icbc.expay.query.req.IcbcQueryExpayCmsEbReq;
import com.gopay.common.domain.bank.icbc.expay.query.req.IcbcQueryExpayCmsReq;
import com.gopay.common.domain.bank.icbc.expay.query.res.IcbcQueryExpayCmsRes;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.log.BisExpaySmsSendLog;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.businesses.ExPayService;

/** 
 * 工行快捷 manager类
 * @ClassName: IcbcExPayManager 
 * @author w_jiqing 
 * @date 2017年6月26日 下午4:40:28  
 */ 
public class IcbcExPayManager {
        
    @Resource(name = "icbcConfig")
    private Map<String, String> icbcConfig;
    
    @Resource(name = "icbcExPayServiceClient")
    private ExPayService icbcExPayServiceClient;
    
    @Resource(name = "bisExpaySmsSendLogDAO")
    private BisExpaySmsSendLogDAO bisExpaySmsSendLogDAO;
    
    @Resource(name = "cpsGeneralMainOrderQueryManager")
    private CpsGeneralMainOrderQueryManager mainOrderQuery;
    
    /** 工行快捷预支付业务
     * @param base
     * @return
     * @throws GopayException 
     */
    public Object sendSms(ExPayBaseMessage base)throws GopayException{
        IcbcPreExpayCmsReq message = buildPrePay(base);                
        BankLogUtils.printExPayManagerSendSmsSendLog(message);
        IcbcPreExpayCmsRes resMsg = (IcbcPreExpayCmsRes) icbcExPayServiceClient.sendSms(message) ;
        resMsg.setOutStlmCd(BankConstants.BANK_LOGO_ICBC);
        BankLogUtils.printExPayManagerSendSmsReturnLog(resMsg);
        return resMsg;
    }
    
 
    /** 
     * 工行快捷支付提交业务
     * @param base
     * @param payMark  true-支付提交  false-验证码重发
     * @return
     * @throws GopayException 
     */
    public Object payment(ExPayBaseMessage base,boolean payMark)throws GopayException{
        IcbcExpayCmsReq reqMsg =buildPay(base,payMark);
        BankLogUtils.printExPayManagerPaymentSendLog(reqMsg);
        IcbcExpayCmsRes resMsg = (IcbcExpayCmsRes) icbcExPayServiceClient.payment(reqMsg);
        resMsg.setOutStlmCd(BankConstants.BANK_LOGO_ICBC);
        BankLogUtils.printExPayManagerPaymentReturnLog(resMsg);
        return resMsg;
    }
    
    /** 工行快捷订单查询业务
     * @param base
     * @return
     * @throws GopayException 
     */
    public Object queryOrder(ExPayBaseMessage base)throws GopayException{
        IcbcQueryExpayCmsReq reqMsg = buildQuery(base);
        BankLogUtils.printExPayManagerQuerySendLog(reqMsg);
        IcbcQueryExpayCmsRes resMsg = (IcbcQueryExpayCmsRes) icbcExPayServiceClient.queryOrder(reqMsg);
        resMsg.setOutStlmCd(BankConstants.BANK_LOGO_ICBC);
        BankLogUtils.printExPayManagerQueryReturnLog(resMsg);
        return resMsg;
    }
    
    /** 
     * 拼装快捷查询报文
     * @param base
     * @return 
     * @author w_jiqing 
     */
    private IcbcQueryExpayCmsReq buildQuery(ExPayBaseMessage base){
        IcbcQueryExpayCmsReq cms = new IcbcQueryExpayCmsReq();
        BeanUtils.copyProperties(base, cms);
        IcbcQueryExpayCmsEbReq eb = new IcbcQueryExpayCmsEbReq();
        IcbcExpayCmsEbPubReq pub = new IcbcExpayCmsEbPubReq();
        IcbcQueryExpayCmsEbInReq in = new IcbcQueryExpayCmsEbInReq();
        
        pub.setTransCode(icbcConfig.get("ICBC.EXPAY.QUERYORDER.TRANSCODE"));
        pub.setCis(icbcConfig.get("ICBC.EXPAY.PREPAY.CIS"));
        pub.setBankCode(icbcConfig.get("ICBC.EXPAY.PREPAY.BANKCODE"));
        pub.setId(icbcConfig.get("ICBC.EXPAY.PREPAY.ID"));
        pub.setTranDate(DateUtils.getCurrDate("yyyyMMdd"));
        pub.setTranTime(DateUtils.getCurrDate("HHmmssSSS"));
        pub.setfSeqno(TransUtils.getPackageID());        
        in.setQrySerialNo("");
        //待查指令包序列号
        in.setQryfSeqno(base.getBankOrderId());
        eb.setPub(pub);
        eb.setIn(in);
        cms.setEb(eb);
        return cms;        
    }
    
    /** 
     * 拼装支付请求报文
     * @param base
     * @param payMark 是否上传验证码标示
     * @return 
     */
    private IcbcExpayCmsReq buildPay(ExPayBaseMessage base,boolean payMark){
        IcbcExpayCmsReq cms = new IcbcExpayCmsReq();
        BeanUtils.copyProperties(base, cms);
        IcbcExpayCmsEbReq eb = new IcbcExpayCmsEbReq();
        IcbcExpayCmsEbPubReq pub = new IcbcExpayCmsEbPubReq();
        IcbcExpayCmsEbInReq in = new IcbcExpayCmsEbInReq();
        
        BisExpaySmsSendLog bessl = null;
        //交易代码        
        pub.setTransCode(icbcConfig.get("ICBC.EXPAY.PAYMENT.TRANSCODE"));
        //集团CIS号
        pub.setCis(icbcConfig.get("ICBC.EXPAY.PREPAY.CIS"));
        //归属银行编号
        pub.setBankCode(icbcConfig.get("ICBC.EXPAY.PREPAY.BANKCODE"));
        //交易日期
        pub.setTranDate(DateUtils.getCurrDate("yyyyMMdd"));
        //交易时间
        pub.setTranTime(DateUtils.getCurrDate("HHmmssSSS"));
        
        //签名时间
        in.setSignTime(DateUtils.getCurrDate("yyyyMMddHHmmssSSS")); 
        
        
        //商户代码
        in.setShopCode(base.getMerID());
        if(payMark){
        	CpsGenMainOrder cpsOrder =mainOrderQuery.get(base.getBankOrderId());
        	in.setsSTime(DateUtils.format(cpsOrder.getCreatedTs()));
        	bessl= bisExpaySmsSendLogDAO.getRemarkIsNotNull(base.getBankOrderId(),SMSType.CASHIER_SMS_SEND.value);
            //支付操作，包号为：国付宝银行订单号，订单查询时，根据国付宝银行订单号即可对单
            pub.setfSeqno(base.getBankOrderId());
            //验证码
            in.setPassword(base.getValidateCode());
            //订单号
            in.setOrderNo(base.getBankOrderId());
            //如果支付时，bis没有收到验证码，银行收到请求，会当成“验证码重发业务”，防止流程异常，验证码为空，置位AAAAAA,银行返回交易失败
            if("".equals(base.getValidateCode())){
                in.setPassword("AAAAAA");
            }
        }else{  
        	CpsGenMainOrder cpsOrder =mainOrderQuery.get(base.getOrderId());
        	in.setsSTime(DateUtils.format(cpsOrder.getCreatedTs()));
        	bessl= bisExpaySmsSendLogDAO.getRemarkIsNotNull(base.getOrderId(),SMSType.CASHIER_SMS_SEND.value);
            //验证码重发操作，包号随机生成，验证码为空
            pub.setfSeqno(TransUtils.getPackageID());
            //验证码为空，代表重发接口
            in.setPassword("");
            //订单号
            in.setOrderNo(base.getOrderId());
        }        
        if(bessl != null){
        	//与对应的高级无界面支付申请接口返回的支付流水号一致
            in.setPaySerialNo(bessl.getRemark());
        }else{
        	in.setPaySerialNo("");
        }
        eb.setPub(pub);
        eb.setIn(in);
        cms.setEb(eb);
        cms.setCustomerID(null);
        return cms;
    }
  
    
    /** 
     * 拼装预支付请求报文 
     * @param base
     * @return 
     */
    private IcbcPreExpayCmsReq buildPrePay(ExPayBaseMessage base){  
        IcbcPreExpayCmsReq cms = new IcbcPreExpayCmsReq();
        BeanUtils.copyProperties(base, cms);
        IcbcPreExpayCmsEbReq eb = new IcbcPreExpayCmsEbReq();
        IcbcExpayCmsEbPubReq pub = new IcbcExpayCmsEbPubReq();
        IcbcPreExpayCmsEbInReq in = new IcbcPreExpayCmsEbInReq();
        CpsGenMainOrder cpsOrder =mainOrderQuery.get(base.getOrderId());
        //交易代码
        pub.setTransCode(icbcConfig.get("ICBC.EXPAY.PREPAY.TRANDCODE"));
        //集团CIS号
        pub.setCis(icbcConfig.get("ICBC.EXPAY.PREPAY.CIS"));
        //归属银行编号
        pub.setBankCode(icbcConfig.get("ICBC.EXPAY.PREPAY.BANKCODE"));
        //证书ID
        pub.setId(icbcConfig.get("ICBC.EXPAY.PREPAY.ID"));
        pub.setTranDate(DateUtils.getCurrDate("yyyyMMdd"));
        pub.setTranTime(DateUtils.getCurrDate("HHmmssSSS"));
        //指令包序列号
        pub.setfSeqno(TransUtils.getPackageID());
        
        in.setSignTime(DateUtils.getCurrDate("yyyyMMddHHmmssSSS"));
        //接入渠道   1：手机2：电话
        in.setPayChannel("1");        
        in.setSubmitTime(DateUtils.format(cpsOrder.getCreatedTs()));
        in.setOrderNo(base.getOrderId());
        in.setOrderAmt(TransUtils.amountConvert2Fen(base.getAmount().toString()));
        //分期付款期数   1代表全额付款
        in.setPayStage("1");
        //分期付款标志
        in.setPayStageFlag("0");
        in.setLanguage1("ZH_CN");
        //商户账号
        in.setShopAcctNo(icbcConfig.get("ICBC.EXPAY.PREPAY.SHOPACCTNO"));
        in.setGoodsNo("");
        in.setGoodsName("pay");
        in.setGoodsNumber("");
        in.setTransferAmt("");
        //检验联名标志
        in.setjUnionFlag("0");
        //支付币种
        in.setCurrType(icbcConfig.get("ICBC.EXPAY.PREPAY.CURRTYPE"));
        //商户代码
        in.setShopCode(base.getMerID());
        //支持订单支付的银行卡种类
        in.setCardFlag(icbcConfig.get("ICBC.EXPAY.PREPAY.CARDFLAG"));
        //通知类型
        in.setNotifyType(icbcConfig.get("ICBC.EXPAY.PREPAY.NOTIFYTYPE"));
        in.setrSendType("0");
        in.setGoodsType("1");
        in.setPhone(base.getMediaId());
        //客户账户末六位
        String cardNo = base.getCardNo();
        in.setCusAcctNo(cardNo.substring(cardNo.length()-6, cardNo.length()));
        //客户别名
        in.setCusAlias(base.getCardHolder());
        in.setThirdFlag("1");
        in.setAgentShopCode("");
        in.setAgentShopName("");
        in.setAgentOrderFlag("");
        in.setBuyerID("");
        in.setRecer("");
        in.setRecAddr("");
        in.setRecPhone("");
        in.setShopAcctSeq("");
        eb.setPub(pub);
        eb.setIn(in);
        cms.setEb(eb);
        return cms;
    }
    
    
    
    

}
